﻿using HBKY.Shop.Common.Extension;
using HBKY.Shop.Common.Helper;
using HBKY.Shop.Common.LogHelper;
using HBKY.Shop.Extensions.Attribute;
using Microsoft.AspNetCore.Builder;
using Microsoft.Extensions.DependencyInjection;
using Microsoft.OpenApi.Models;
using Swashbuckle.AspNetCore.Filters;
using Swashbuckle.AspNetCore.SwaggerUI;
using System;
using System.IO;
using System.Linq;
using System.Runtime.InteropServices;
using static HBKY.Shop.Extensions.ServiceExtensions.CustomApiVersion;

namespace HBKY.Shop.Extensions.ServiceExtensions
{
    public static class SwaggerSetup
    {
        /// <summary>
        /// Swagger 中间件
        /// </summary>
        /// <param name="app"></param>
        /// <param name="pathBase"></param>
        public static void UseSwaggerSetup(this IApplicationBuilder app)
        {
            var apiName = Appsettings.Option("Startup", "ApiName");
            var routePrefix = Appsettings.Option("Startup", "RoutePrefix");
            app.UseSwagger();
            app.UseSwaggerUI(c =>
            {
                foreach (ApiGroup version in Enum.GetValues(typeof(ApiGroup)))
                {
                    c.SwaggerEndpoint($"/swagger/{version}/swagger.json", $"{version.GetDescription()}({version})");
                    //c.RoutePrefix = "";
                    //接口折叠起来
                    c.DocExpansion(DocExpansion.None);
                }
            });

        }

        /// <summary>
        /// 注入 Swagger 服务到容器内
        /// </summary>
        /// <param name="services"></param>
        public static void AddSwaggerSetup(this IServiceCollection services)
        {
            if (services == null) throw new ArgumentNullException(nameof(services));

            var basePath = AppContext.BaseDirectory;
            var apiName = Appsettings.Option("Startup", "ApiName");

            services.AddSwaggerGen(options => {

                typeof(ApiGroup).GetEnumNames().ToList().ForEach(version =>
                {
                    options.SwaggerDoc(version, new OpenApiInfo()
                    {
                        Version = version,
                        Title = $"{apiName} 接口文档—{RuntimeInformation.FrameworkDescription}",
                        Description = $"{apiName} HTTP API {version}",
                        Contact = new OpenApiContact() { Url = new Uri("http://www.baidu.com"), Name = "niuniufund" },
                    });
                    options.OrderActionsBy(o => o.RelativePath);
                });

                try
                {
                    // //默认的第二个参数是false，这个是controller的注释，记得修改兼容Linux 使用小写
                    options.IncludeXmlComments($"{Path.Combine(basePath, $"{apiName?.ToLower()}.xml")}", true);

                    //这个就是Model层的xml文件名
                    options.IncludeXmlComments(Path.Combine(basePath, "hbky.shop.entity.xml"));
                    options.IncludeXmlComments(Path.Combine(basePath, "hbky.shop.model.xml"));
                    //这个就是Entity层的xml文件名
                    options.IncludeXmlComments(Path.Combine(basePath, "hbky.shop.iservice.xml"));

                }
                catch (Exception ex)
                {
                    LogManagerNlog.LogError(ex, "hbky.shop.model.xml 和 hbky.shop.entity.xml丢失");
                }

                options.OperationFilter<SecurityRequirementsOperationFilter>();

                options.AddSecurityDefinition("oauth2", new OpenApiSecurityScheme
                {
                    Description = "JWT授权(数据将在请求头中进行传输) 直接在下框中输入Bearer {token}(注意两者之间是一个【空格】)",
                    Name = "Authorization",//jwt默认的参数名称
                    In = ParameterLocation.Header,//jwt默认存放Authorization信息的位置(请求头中)
                    Type = SecuritySchemeType.ApiKey,
                    Scheme = "Bearer",
                });
            });
        }
    }

    /// <summary>
    /// api 版本
    /// </summary>
    public class CustomApiVersion
    {
        /// <summary>
        /// Api接口版本 自定义
        /// </summary>
        public enum ApiVersions
        {
            /// <summary>
            /// V1 版本
            /// </summary>
            V1 = 1,
        }
    }
}
